/**
 * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 */

package com.iwindplus.boot.mongo.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.iwindplus.boot.domain.DocDbBaseDO;
import com.iwindplus.boot.domain.constant.CommonConstant;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * mongo业务层基础接口类.
 *
 * @param <T> 对象
 * @author zengdegui
 * @since 2019/8/9
 */
public interface MongoBaseService<T extends DocDbBaseDO> {
    /**
     * 插入单个.
     *
     * @param entity 对象
     * @return T
     */
    T save(T entity);

    /**
     * 插入（批量）.
     *
     * @param entities 对象集合
     * @return boolean
     */
    default Collection<T> saveBatch(Collection<T> entities) {
        return this.saveBatch(entities, CommonConstant.NumberConstant.NUMBER_ONE_THOUSAND);
    }

    /**
     * 插入（批量）.
     *
     * @param entities  对象集合
     * @param batchSize batchSize 批次大小
     * @return boolean
     */
    Collection<T> saveBatch(Collection<T> entities, int batchSize);

    /**
     * 插入或修改（批量）.
     *
     * @param entities 对象集合
     * @return boolean
     */
    default boolean saveOrUpdateBatch(Collection<T> entities) {
        return this.saveOrUpdateBatch(entities, CommonConstant.NumberConstant.NUMBER_ONE_THOUSAND);
    }

    /**
     * 插入或修改（批量）.
     *
     * @param entities  对象集合
     * @param batchSize batchSize 批次大小
     * @return boolean
     */
    boolean saveOrUpdateBatch(Collection<T> entities, int batchSize);

    /**
     * 根据主键删除.
     *
     * @param id 主键
     * @return boolean
     */
    default boolean removeById(String id) {
        return this.removeById(id, Boolean.TRUE);
    }

    /**
     * 根据主键删除.
     *
     * @param id      主键
     * @param deleted 是否真删
     * @return boolean
     */
    default boolean removeById(String id, boolean deleted) {
        return this.removeByIds(Arrays.asList(id), deleted);
    }

    /**
     * 删除（批量）.
     *
     * @param ids 主键集合
     * @return boolean
     */
    default boolean removeByIds(Collection<?> ids) {
        return this.removeByIds(ids, Boolean.TRUE);
    }

    /**
     * 删除（批量）.
     *
     * @param ids     主键集合
     * @param deleted 是否真删
     * @return boolean
     */
    boolean removeByIds(Collection<?> ids, boolean deleted);

    /**
     * 删除.
     *
     * @param query 条件
     * @return boolean
     */
    default boolean remove(Query query) {
        return this.remove(query, Boolean.TRUE);
    }

    /**
     * 删除.
     *
     * @param query   条件
     * @param deleted 是否真删
     * @return boolean
     */
    boolean remove(Query query, boolean deleted);

    /**
     * 根据主键修改.
     *
     * @param entity 对象
     * @return boolean
     */
    boolean updateById(T entity);

    /**
     * 根据条件修改.
     *
     * @param entity 对象
     * @param query  条件
     * @return boolean
     */
    boolean update(T entity, Query query);

    /**
     * 修改（批量）.
     *
     * @param entities 对象
     * @return boolean
     */
    default boolean updateBatchById(Collection<T> entities) {
        return this.updateBatchById(entities, CommonConstant.NumberConstant.NUMBER_ONE_THOUSAND);
    }

    /**
     * 修改（批量）.
     *
     * @param entities  对象
     * @param batchSize 批次大小
     * @return boolean
     */
    boolean updateBatchById(Collection<T> entities, int batchSize);

    /**
     * 列表.
     *
     * @param page  分页
     * @param query 条件
     * @param <E>   对象
     * @return <E extends IPage<T>>
     */
    <E extends IPage<T>> E page(E page, Query query);

    /**
     * 查询所有.
     *
     * @return List<T>
     */
    List<T> list();

    /**
     * 查询所有.
     *
     * @param query 条件
     * @return List<T>
     */
    List<T> list(Query query);

    /**
     * 根据主键查询.
     *
     * @param id 主键
     * @return T
     */
    T getById(String id);

    /**
     * 查询单个.
     *
     * @param query 条件
     * @return T
     */
    T getOne(Query query);

    /**
     * 查询总数.
     *
     * @param query 条件
     * @return long
     */
    long count(Query query);
}
